.text
.align 8
.section .rodata
.LC0:
    .string "Usage: %s filename\n"
.LC1:
    .string "r"
.LC2:
    .string "I could not open the file \"%s\"\n"
.LC3:
    .string ".red"
.LC4:
    .string "w"
.LC5:
    .string "Cannot create output file.\n"
.LC6:
    .string "Error in closing files\n"

.text
.globl main
.type main, @function
main:
    pushq %rbp
    movq %rsp, %rbp

    subq $80, %rsp
    // 分配局部变量
    // in: -8(%rbp)
    // out: -16(%rbp)
    // ch: -20(%rbp)
    // name: -60(%rbp)
    // count: -64(%rbp)
    // argc: -68(%rbp)
    // argv: -76(%rbp)

    movq %rsi, -76(%rbp)
    movl %edi, -68(%rbp)

    // 测试一下打印参数
    /**
    movq 0(%rsi), %rdi
    movl $0, %eax
    call printf
    */

    cmpl $2, -68(%rbp) /* argc */
    jge .CONTINUE
.EXIT_ARGS_ERROR:
    leaq stderr(%rip), %rax
    movq (%rax), %rdi
    leaq .LC0(%rip), %rsi
    movq -76(%rbp) /* argv */, %rax
    movq 0(%rax), %rdx
    call fprintf
    movl $1, %edi
    call exit
.CONTINUE:
    movq -76(%rbp) /* argv */, %rax
    movq 8(%rax), %rdi
    leaq .LC1(%rip), %rsi
    call fopen
    movq %rax, -8(%rbp) /* in */
    cmpq $0, %rax
    jne .CONTINUE1
.EXIT_OPEN_READ_FILE_FAILED:
    leaq stderr(%rip), %rax
    movq (%rax), %rdi
    leaq .LC2(%rip), %rsi
    movq -76(%rbp) /* argv */, %rax
    movq 8(%rax), %rdx
    call fprintf
    movl $3, %edi
    call exit
.CONTINUE1:
    leaq -60(%rbp) /* name */, %rdi
    movq -76(%rbp) /* argv */, %rax
    movq 8(%rax), %rsi
    movl $35, %edx
    call strncpy
    leaq -60(%rbp) /* name */, %rax
    // 以下两句等效于 movb $0, (%rax, 35, 1)
    addq $35, %rax
    movb $0, (%rax)

    leaq -60(%rbp) /* name */, %rdi
    leaq .LC3(%rip), %rsi
    call strcat

    leaq -60(%rbp) /* name */, %rdi
    leaq .LC4(%rip), %rsi
    call fopen
    movq %rax, -16(%rbp) /* out */
    cmpq $0, %rax
    jne .CONTINUE2
.EXIT_OPEN_WRITE_FILE_FAILED:
    leaq stderr(%rip), %rax
    movq (%rax), %rdi
    leaq .LC5(%rip), %rsi
    call fprintf
    movl $3, %edi
    call exit
.CONTINUE2:
    jmp .WHILE_34_COMPARE
.WHILE_34_ENTER:
    movl -64(%rbp) /* count */, %eax
    incl -64(%rbp) /* count */
    cltq
    xorq %rdx, %rdx
    movq $3, %rcx
    divq %rcx
    cmpq $0, %rdx
    jne .WHILE_34_INCR
    movl -20(%rbp) /* ch */, %edi
    movq -16(%rbp) /* out */, %rsi
    call putc
.WHILE_34_INCR:
    // nothing to do
.WHILE_34_COMPARE:
    movq -8(%rbp) /* in */, %rdi
    call getc
    movl %eax, -20(%rbp) /* ch */
    cmpl $-1, %eax
    jne .WHILE_34_ENTER

    movq -8(%rbp) /* in */, %rdi
    call fclose
    cmpl $0, %eax
    jne .FCLOSE_ERROR
    movq -16(%rbp) /* out */, %rdi
    call fclose
    cmpl $0, %eax
    jne .FCLOSE_ERROR
    jmp .EXIT_SUCCESS
.FCLOSE_ERROR:
    leaq stderr(%rip), %rax
    movq (%rax), %rdi
    leaq .LC6(%rip), %rsi
    call fprintf
.EXIT_SUCCESS:
    movl $0, %eax
    leave
    ret